home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Collection of Tools & Utilities
/
Collection of Tools and Utilities.iso
/
graphic
/
cheetah.zip
/
CGETZC.C
< prev
next >
Wrap
C/C++ Source or Header
|
1992-08-21
|
6KB
|
252 lines
/* cgetzc.c
*
* CHAINED mode version.
* NOTE that in this mode BPERROW is a permanent constant, and always equal to
* BPERROW_CHAINED.
*
* Description:
* Get screen image in ZCompact format.
*
* Function list:
* CgetZCompact().
*
* Portability: BORLANDC
* (c) erdy 1992
* $Header: $
*/
#pragma inline
#include <limits.h>
#include <alloc.h> /* farcoreleft() */
#include "far.h"
#include "vgaprefx.h"
#include "vgadrv.h"
#include "screen.h"
#include "mxcpy.h"
static unsigned char near colormap[ZC_CMAPSIZE];
Image far *CgetZCompact(unsigned int x, unsigned int y, int nc, int nr, int backcolor)
{
unsigned char far *mem;
char far *p;
Image far *ip;
auto unsigned int sz;
auto unsigned long coreleft;
auto unsigned int used; /* ßτÑΓτ¿¬ íá⌐Γ */
auto unsigned int row, col;
coreleft = (unsigned long)nc * nr;
coreleft += MAXCOLORS;
if (coreleft > UINT_MAX)
sz = UINT_MAX;
else
sz = coreleft;
if ((coreleft = farcoreleft()/2) > UINT_MAX)
coreleft = UINT_MAX;
if (sz > coreleft)
coreleft = sz;
coreleft -= 6;
If_Overflow:
if ((p = getmem(sz)) == NULL) {
Abort:
scerror = ER_OUTOFMEM;
return(NULL);
}
sz -= 6;
used = 0;
_segment(mem) = VGA_SEG0/*Scdraw_seg*/;
_offset(mem) = VIDEO_CADDRESS(x, y);
asm cld;
asm push ds;
/*
* Build color map.
*
* Colormap is placed at es:0.
*/
/* Clear color map */
asm les di, p; /* Segment p -> es */
_AL = 0; _CX = MAXCOLORS;
asm rep stosb;
asm mov dx, BPERROW_CHAINED;
asm sub dx, nc; /* To add per each row */
asm xor ah, ah; /* It will be counter */
asm xor bh, bh; /* High byte of index */
asm lds si, mem; /* Load video address */
asm mov cx, nr;
L3:
asm push cx;
asm mov cx, nc; /* Column counter */
L1:
asm lodsb; /* Load color at ds:[si], advance si */
if (backcolor < MAXCOLORS) {
asm cmp al, byte ptr backcolor;
asm je C1;
}
asm mov bl, al;
asm xor bh, bh;
asm cmp byte ptr es:[bx], bh; /* Is table entry busy ? (bh = 0) */
asm jne C1; /* == 0 - empty */
asm inc ah; /* Count color */
asm cmp ah, ZC_CMAPSIZE;/* Out of map ? */
asm jl C2;
/* Map is full */
asm pop cx;
asm pop ds;
retmem(p);
scerror = ER_OUTOFMAP;
return(0);
C2:
asm mov es:[bx], ah; /* Store color index */
C1:
asm loop L1;
asm add si, dx;
asm pop cx;
asm loop L3;
if (backcolor < MAXCOLORS) { /* Backcolor mapped to 0 */
asm mov bx, backcolor;
asm mov byte ptr es:[bx], 0; /* Store 0 */
}
/*
* Now build image.
*/
_DI = MAXCOLORS; /* _offset(p) = 0 !! */
_SI = _offset(mem);
/* Registers on entrance:
* es - data segment, di - data offset
* ds - video ram segment, si - video ram offset
*/
for (row = 0; row < nr; row++) {
asm push si;
asm mov cx, nc; /* Set column counter */
asm mov ah, [si];
asm inc ah; /* Make a sure that not equal to 1st color*/
asm xor dx, dx; /* Clear the counter */
L2:
asm lodsb; /* Load color at ds:[si], advance si */
asm cmp ah, al; /* Same color */
asm jne C3;
asm inc dx; /* Count the color */
C4:
asm loop L2;
/* Map color of last pixel */
asm xor bx, bx;
asm mov bl, ah;
asm mov al, es:[bx];
asm or al, al; /* If 0 - backcolor, so skip it */
asm jne C3;
goto C6;
/*
* Store image data.
*/
C3:
asm push ax; /* Save new color */
/* Map color */
asm xor bx, bx;
asm mov bl, ah;
asm mov ah, es:[bx];
while (_DX > 0xFF) { /* Very long counter (?) */
asm mov al, ah;
asm stosb;
asm mov byte ptr es:[di], 0xFF;
asm inc di;
used += 2;
_DX -= 0xFF;
}
if (_DX) {
if (_DX <= 3) {
asm mov al, dl; /* Counter */
asm ror al, 1; /* shl al, 6 */
asm ror al, 1;
asm or al, ah; /* Color code */
asm stosb;
used++;
}
else {
asm mov al, ah; /* Color code */
asm stosb;
asm mov al, dl;
asm stosb;
used += 2;
}
}
if (used > sz) { /* Out of space */
asm pop ax;
asm pop ds;
retmem(p);
if (sz == coreleft)
goto Abort;
sz = coreleft + 6;
goto If_Overflow;
}
asm pop ax;
asm mov ah, al; /* Put new color */
asm mov dx, 1; /* And count it */
asm jcxz C6;
goto C4;
/* End of Loop */
C6:
/* Write the EOL */
asm xor al, al;
asm stosb;
asm stosb;
used += 2;
asm pop si;
asm add si, BPERROW_CHAINED; /* Advance to next row */
}
asm pop ds;
for (col = 0; col < MAXCOLORS; col++) {
if ((row = p[col]) != 0)
colormap[row] = col;
}
if ((ip = (Image far *)getmem((unsigned long)used + ZC_CMAPSIZE + sizeof(Image))) == NULL) {
retmem(p);
scerror = ER_OUTOFMEM;
return(NULL);
}
/* _offset(ip) is equal to 0 ! */
/* Copy data */
_offset(ip) = ZC_CMAPSIZE + sizeof(Image);
_offset(p) = MAXCOLORS;
_mxcpy(p, ip, used);
/* Copy colormap */
_DI = sizeof(Image);
_ES = _segment(ip);
_CX = ZC_CMAPSIZE;
asm lea si, colormap;
asm rep movsb; /* Copy ds:[si] to es:[di] */
_offset(p) = 0;
retmem(p);
/* Establish image */
_offset(ip) = 0;
ip->d.size = used;
ip->d.twidth = ip->d.width = nc;
ip->d.theight = ip->d.height = nr;
ip->d.x = ip->d.y = 0;
ip->d.ncolormaps = 1;
ip->d.format = ZCompact;
p = (char far *)ip + sizeof(Image);
_farnormal(p); /* Offset p must be 0 ! */
_offset(p) = ZC_CMAPSIZE;
ip->d.data = p;
return(ip);
}